/**
 * 
 */
package dt.inlee.common.util;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import dt.inlee.common.constant.CommonEnumType;
import dt.inlee.common.exception.FrameworkException;
import dt.inlee.domain.LogInfo;
import dt.inlee.system.service.LogInfoService;

/**
 * @功能说明：日志工具类
 * @作者： xgyin
 * @创建日期： 2011-3-22
 */

public class LogUtil {
	@Autowired
	private LogInfoService logInfoService;

	private static LogUtil instance;

	/** 系统日志 */
	private static Logger log = Logger.getLogger(LogUtil.class);

	private LogUtil() {
	}

	/**
	 * 利用单利模式获取一个LogUtil对象
	 * 
	 * @return
	 * @throws FrameworkException
	 */
	public static synchronized LogUtil getInstance() throws FrameworkException {
		if (BaseUtil.isEmpty(instance))
			instance = (LogUtil) ContextLoaderUtil.load("logUtil");
		return instance;
	}

	/**
	 * 针对业务的登录方法，将内容记录到日志
	 * 
	 * @throws FrameworkException
	 */
	public void loginExecution() throws FrameworkException {
		this.execution(null, CommonEnumType.OperateType.登录.name(), "登录系统");
	}

	/**
	 * 针对业务的登录方法，将内容记录到日志
	 * 
	 * @throws FrameworkException
	 */
	public void logoutExecution() throws FrameworkException {
		this.execution(null, CommonEnumType.OperateType.退出.name(), "退出系统");
	}

	/**
	 * 针对业务的新增方法，将内容记录到日志
	 * 
	 * @param entity
	 * @throws FrameworkException
	 */
	public void addExecution(String businessObj) throws FrameworkException {
		this.addExecution(null, businessObj);
	}

	/**
	 * 针对业务的新增方法，将内容记录到日志
	 * 
	 * @param entity
	 * @throws FrameworkException
	 */
	public void addExecution(Object entity) throws FrameworkException {
		this.addExecution(entity, null);
	}

	/**
	 * 针对业务的新增方法，将内容记录到日志
	 * 
	 * @param entity
	 * @param businessObj
	 * @throws FrameworkException
	 */
	public void addExecution(Object entity, String businessObj) throws FrameworkException {
		this.execution(entity, CommonEnumType.OperateType.新增.name(), businessObj);
	}

	/**
	 * 针对业务的修改方法，将内容记录到日志
	 * 
	 * @param businessObj
	 * @throws FrameworkException
	 */
	public void modifyExecution(String businessObj) throws FrameworkException {
		this.modifyExecution(null, businessObj);

	}

	/**
	 * 针对业务的修改方法，将内容记录到日志
	 * 
	 * @param entity
	 * @throws FrameworkException
	 */
	public void modifyExecution(Object entity) throws FrameworkException {
		this.modifyExecution(entity, null);

	}

	/**
	 * 针对业务的修改方法，将内容记录到日志
	 * 
	 * @param entity
	 * @param businessObj
	 * @throws FrameworkException
	 */
	public void modifyExecution(Object entity, String businessObj) throws FrameworkException {
		this.execution(entity, CommonEnumType.OperateType.修改.name(), businessObj);
	}

	/**
	 * 针对业务的删除方法，将内容记录到日志
	 * 
	 * @param businessObj
	 * @throws FrameworkException
	 */
	public void deleteExecution(String businessObj) throws FrameworkException {
		this.deleteExecution(null, businessObj);
	}

	/**
	 * 针对业务的删除方法，将内容记录到日志
	 * 
	 * @param entity
	 * @throws FrameworkException
	 */
	public void deleteExecution(Object entity) throws FrameworkException {
		this.deleteExecution(entity, null);
	}

	/**
	 * 针对业务的删除方法，将内容记录到日志
	 * 
	 * @param entity
	 * @param businessObj
	 * @throws FrameworkException
	 */
	public void deleteExecution(Object entity, String businessObj) throws FrameworkException {
		this.execution(entity, CommonEnumType.OperateType.删除.name(), businessObj);
	}

	/**
	 * 针对业务的查看详情方法，将内容记录到日志
	 * 
	 * @param entity
	 * @throws FrameworkException
	 */
	public void queryDetailExecution(Object entity) throws FrameworkException {
		this.queryDetailExecution(entity, null);
	}

	/**
	 * 针对业务的查看详情方法，将内容记录到日志
	 * 
	 * @param entity
	 * @param businessObj
	 * @throws FrameworkException
	 */
	public void queryDetailExecution(Object entity, String businessObj) throws FrameworkException {
		this.execution(entity, CommonEnumType.OperateType.查看.name(), businessObj);
	}

	/**
	 * 针对业务的增删改查方法，将内容记录到日志
	 * 
	 * @param entity
	 * @param operateType: 操作类型(增删改查)
	 * @param operateType: 操作类型(增删改查)
	 * @throws FrameworkException
	 */
	private void execution(Object entity, String operateType, String businessObject) throws FrameworkException {

		LogInfo logEntity = new LogInfo();
		// 操作类型
		logEntity.setOptype(operateType);
		if (!BaseUtil.isEmpty(entity)) {
			// 操作对象
			logEntity.setObjectname(BaseUtil.isEmpty(businessObject) ? entity.getClass().getSimpleName()
					: businessObject);
			// 数据id
			logEntity.setDataid((String) getEntityId(entity, "getId"));
		} else {
			// 操作对象
			logEntity.setObjectname(BaseUtil.isEmpty(businessObject) ? null : businessObject);
		}
		logInfoService.addLogInfo(logEntity);

	}

	/**
	 * 通过对象和方法名获得值
	 * 
	 * @param entity
	 * @param methodName
	 * @return
	 */
	private static Object getEntityId(Object entity, String methodName) {
		try {
			if (!BaseUtil.isEmpty(entity) && !BaseUtil.isEmpty(methodName)) {
				Method method = entity.getClass().getMethod(methodName);
				if (!BaseUtil.isEmpty(method))
					return method.invoke(entity);
			}
		} catch (NoSuchMethodException noSuchMethodException) {
			log.info(entity.getClass() + "没有找到" + methodName + "()方法", noSuchMethodException);
		} catch (Exception ex) {
			log.info("Exception", ex);
		}
		return null;
	}

}
